// utils/request.js
// const BASE_URL = 'http://139.9.251.34:100/miniprogram';//测试
// const BASE_URL = 'http://uat.swiftsafe.ca/miniprogram';//uat
const BASE_URL = 'https://admin.swiftsafe.ca/miniprogram'; //正式https://admin.swiftsafe.ca/

// 错误码映射
const ERROR_MESSAGES = {
  400: '请求参数错误',
  401: '未授权，请重新登录',
  403: '权限不足',
  404: '请求的资源不存在',
  405: '请求方法不允许',
  408: '请求超时',
  429: '请求过于频繁，请稍后再试',
  500: '服务器内部错误',
  502: '网关错误',
  503: '服务暂时不可用',
  504: '网关超时'
};

// 网络错误映射
const NETWORK_ERROR_MESSAGES = {
  'fail': '网络连接失败',
  'timeout': '请求超时',
  'abort': '请求被中断'
};

// 请求去重管理
const pendingRequests = new Map();
const requestCache = new Map();

function normalizeUrl(path) {
  if (!path) return BASE_URL;
  if (path.startsWith('http')) return path;
  return `${BASE_URL}${path.startsWith('/') ? '' : '/'}${path}`;
}

// 获取token
function getToken() {
  try {
    return wx.getStorageSync('token') || '';
  } catch (e) {
    console.error('获取token失败：', e);
    return '';
  }
}

// 清除用户数据
function clearUserData() {
  try {
    wx.removeStorageSync('token');
    wx.removeStorageSync('user');
  } catch (e) {
    console.error('清除用户数据失败：', e);
  }
}

// 显示错误提示
function showError(message, duration = 3000) {
  wx.showToast({
    title: message,
    icon: 'none',
    duration: duration
  });
}

// 处理响应错误
function handleResponseError(res) {
  const statusCode = res.statusCode;
  const body = res.data;
  
  let errorMessage = '请求失败';
  
  // 优先使用服务器返回的错误信息
  if (body && body.msg) {
    errorMessage = body.msg;
  } else if (body && body.message) {
    errorMessage = body.message;
  } else if (ERROR_MESSAGES[statusCode]) {
    errorMessage = ERROR_MESSAGES[statusCode];
  }
  
  // 特殊处理401未授权
  if (statusCode === 401) {
    clearUserData();
    // 延迟跳转到登录页，让用户看到错误提示
    setTimeout(() => {
      wx.redirectTo({
        url: '/pages/register/register'
      });
    }, 1500);
  }
  
  showError(errorMessage);
  
  return {
    message: errorMessage,
    statusCode,
    data: body
  };
}

// 处理网络错误
function handleNetworkError(err) {
  let errorMessage = '网络连接失败';
  
  if (err.errMsg) {
    const errMsg = err.errMsg.toLowerCase();
    if (errMsg.includes('timeout')) {
      errorMessage = '请求超时，请检查网络连接';
    } else if (errMsg.includes('fail')) {
      errorMessage = '网络连接失败，请检查网络设置';
    } else if (errMsg.includes('abort')) {
      errorMessage = '请求被中断';
    }
  }
  
  showError(errorMessage);
  
  return {
    message: errorMessage,
    type: 'network',
    originalError: err
  };
}

// 生成请求唯一标识
function generateRequestKey(url, method, data) {
  const dataStr = JSON.stringify(data || {});
  return `${method}:${url}:${dataStr}`;
}

// 检查是否有相同的请求正在进行
function hasPendingRequest(requestKey) {
  return pendingRequests.has(requestKey);
}

// 添加正在进行的请求
function addPendingRequest(requestKey, promise) {
  pendingRequests.set(requestKey, promise);
}

// 移除正在进行的请求
function removePendingRequest(requestKey) {
  pendingRequests.delete(requestKey);
}

// 获取缓存的请求结果
function getCachedRequest(requestKey) {
  return requestCache.get(requestKey);
}

// 缓存请求结果
function setCachedRequest(requestKey, result, cacheTime = 30000) {
  requestCache.set(requestKey, {
    result,
    timestamp: Date.now(),
    cacheTime
  });
  
  // 设置过期清理
  setTimeout(() => {
    requestCache.delete(requestKey);
  }, cacheTime);
}

function request(options = {}) {
  const { 
    url, 
    method = 'GET', 
    data = {}, 
    header = {},
    showLoading = false,
    loadingText = '请求中...',
    showError = true,
    preventDuplicate = true,
    enableCache = false,
    cacheTime = 30000
  } = options;
  
  // 生成请求唯一标识
  const requestKey = generateRequestKey(url, method, data);
  
  // 检查是否有相同的请求正在进行
  if (preventDuplicate && hasPendingRequest(requestKey)) {
    console.log('检测到重复请求，返回正在进行的请求结果');
    return pendingRequests.get(requestKey);
  }
  
  // 检查缓存
  if (enableCache && method === 'GET') {
    const cached = getCachedRequest(requestKey);
    if (cached && (Date.now() - cached.timestamp) < cached.cacheTime) {
      console.log('返回缓存结果');
      return Promise.resolve(cached.result);
    }
  }
  
  // 获取token并添加到请求头
  const token = getToken();
  const requestHeader = {
    'content-type': 'application/json',
    ...header
  };
  
  // 如果有token，添加到请求头
  if (token) {
    requestHeader.token = token;
  }
  
  const requestPromise = new Promise((resolve, reject) => {
    // 显示加载提示
    if (showLoading) {
      wx.showLoading({ title: loadingText });
    }
    
    wx.request({
      url: normalizeUrl(url),
      method,
      data,
      header: requestHeader,
      success(res) {
        if (showLoading) {
          wx.hideLoading();
        }
        
        const statusCode = res.statusCode;
        const body = res.data;
        
        if (statusCode >= 200 && statusCode < 300) {
          // 请求成功
          // 缓存GET请求结果
          if (enableCache && method === 'GET') {
            setCachedRequest(requestKey, body, cacheTime);
          }
          resolve(body);
        } else {
          // 请求失败
          const error = handleResponseError(res);
          if (showError) {
            // 错误提示已在handleResponseError中显示
          }
          reject(error);
        }
      },
      fail(err) {
        if (showLoading) {
          wx.hideLoading();
        }
        
        // 网络错误
        const error = handleNetworkError(err);
        if (showError) {
          // 错误提示已在handleNetworkError中显示
        }
        reject(error);
      }
    });
  });
  
  // 添加去重管理
  if (preventDuplicate) {
    addPendingRequest(requestKey, requestPromise);
    
    // 请求完成后移除
    requestPromise.finally(() => {
      removePendingRequest(requestKey);
    });
  }
  
  return requestPromise;
}

// 便捷方法：带加载提示的请求
function requestWithLoading(options = {}) {
  return request({
    ...options,
    showLoading: true
  });
}

// 便捷方法：静默请求（不显示错误提示）
function silentRequest(options = {}) {
  return request({
    ...options,
    showError: false
  });
}

// 便捷方法：带缓存的GET请求
function cachedRequest(options = {}) {
  return request({
    ...options,
    enableCache: true,
    method: 'GET'
  });
}

// 便捷方法：允许重复的请求（用于某些特殊场景）
function allowDuplicateRequest(options = {}) {
  return request({
    ...options,
    preventDuplicate: false
  });
}

// 清理所有缓存
function clearCache() {
  requestCache.clear();
}

// 清理所有正在进行的请求
function clearPendingRequests() {
  pendingRequests.clear();
}

// 文件上传函数
// 注意：wx.uploadFile 会自动设置 Content-Type: multipart/form-data
// 并生成正确的 boundary 参数，无需手动设置
function uploadFile(options = {}) {
  const {
    filePath,
    name = 'file',
    formData = {},
    url,
    showLoading = true,
    loadingText = '上传中...',
    showError = true
  } = options;
  
  // 验证必要参数
  if (!filePath) {
    const error = { message: '文件路径不能为空' };
    if (showError) showError(error.message);
    return Promise.reject(error);
  }
  
  if (!url) {
    const error = { message: '上传URL不能为空' };
    if (showError) showError(error.message);
    return Promise.reject(error);
  }
  
  // 获取token
  const token = getToken();
  
  // 创建formData副本，避免修改原始对象
  const uploadFormData = { ...formData };
  
  // 添加token到formData
  if (token) {
    uploadFormData.token = token;
  }
  
  // 验证 formData 格式
  const formDataKeys = Object.keys(uploadFormData);
  
  // 确保 formData 中的所有值都是字符串
  Object.keys(uploadFormData).forEach(key => {
    if (typeof uploadFormData[key] !== 'string') {
      uploadFormData[key] = String(uploadFormData[key]);
    }
  });
  
  return new Promise((resolve, reject) => {
    // 显示加载提示
    if (showLoading) {
      wx.showLoading({ title: loadingText });
    }
    
    // wx.uploadFile 会自动设置 Content-Type: multipart/form-data
    // 并生成正确的 boundary 参数
    wx.uploadFile({
      url: normalizeUrl(url),
      filePath: filePath,
      name: name,
      formData: uploadFormData,
      header: {
        token
      },
      success(res) {
        if (showLoading) {
          wx.hideLoading();
        }
        
        try {
          const data = JSON.parse(res.data);
          
          if (res.statusCode >= 200 && res.statusCode < 300) {
            resolve(data);
          } else {
            const error = {
              message: data.msg || data.message || '上传失败',
              statusCode: res.statusCode,
              data: data
            };
            
            if (showError) {
              showError(error.message);
            }
            reject(error);
          }
        } catch (e) {
          const error = {
            message: '上传响应解析失败',
            statusCode: res.statusCode,
            data: res.data
          };
          
          if (showError) {
            showError(error.message);
          }
          reject(error);
        }
      },
      fail(err) {
        if (showLoading) {
          wx.hideLoading();
        }
        
        const error = handleNetworkError(err);
        if (showError) {
          // 错误提示已在handleNetworkError中显示
        }
        reject(error);
      }
    });
  });
}

module.exports = {
  request,
  requestWithLoading,
  silentRequest,
  cachedRequest,
  allowDuplicateRequest,
  clearCache,
  clearPendingRequests,
  uploadFile,
  BASE_URL,
  getToken,
  clearUserData
};


